package com.dawn.framework.crypto.code.wrapper;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2025/3/11 15:22
 */
public class DecryptHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public DecryptHttpServletRequestWrapper(HttpServletRequest request, String decryptedBody)
            throws IOException {
        super(request);
        this.body = decryptedBody.getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return byteArrayInputStream.available() == 0;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
                throw new UnsupportedOperationException();
            }

            @Override
            public int read() {
                return byteArrayInputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    @Override
    public String getParameter(String name) {
        // 优先从解密后的JSON中解析参数（针对@RequestBody）
        try {
            JsonNode jsonNode = new ObjectMapper().readTree(body);
            return jsonNode.has(name) ? jsonNode.get(name).asText() : super.getParameter(name);
        } catch (Exception e) {
            return super.getParameter(name);
        }
    }

}